<!-- 投票详情 -->
<template>
  <app-page card full>
    <template #header>投票详情</template>

    <app-page-main>
      <div class="count-main">
        <div class="count-main__meet">
          <div class="count-main__meet-body">
            <div
              class="count-main__meet-wrapper"
              :style="{
                '--location-column': data.maxCol,
                '--location-row': data.maxRow,
              }"
            >
              <div class="area-wrapper--top">
                <div class="area-wrapper--top-locale" v-for="order in data.maxCol" :key="order">
                  {{ order }}列
                </div>
              </div>
              <div class="area-wrapper--left">
                <div class="area-wrapper--left-locale" v-for="order in data.maxRow" :key="order">
                  {{ order }}排
                </div>
              </div>
              <div
                class="count-main__meet-wrapper--area"
                :style="{
                  'justify-content': data.maxCol > 22 ? 'flex-start' : 'center',
                  width: data.maxCol > 22 ? 'fit-content' : 'auto',
                }"
              >
                <div
                  :class="[
                    'ellipsis location-wrapper-square',
                    item.type === 1 && 'voted',
                    item.type === 2 && 'unvoted',
                  ]"
                  v-for="(item, index) in gridCells"
                  :key="index"
                >
                  {{ item.name }}
                </div>
              </div>
            </div>
          </div>
        </div>
        <div class="count-main__stat" ref="statRef">
          <div class="app-flex-mid vote-result">
            <span>列席人数{{ pageData.detail.attendance }}人</span>
            <span>应投{{ pageData.detail.voteUserCount }}人</span>
            <span>已投{{ pageData.detail.votedCount }}人</span>
            <span>未投{{ pageData.detail.unVotedCount }}人</span>
          </div>
          <div class="count-main__stat-header">
            <div class="count-main__stat-header--title">投票名称：{{ data.voteDetail.title }}</div>
            <div class="count-main__stat-header--time">
              投票时间：{{ data.voteDetail.startTime }}至{{ data.voteDetail.endTime }}
            </div>
          </div>
          <div class="count-main__stat-body">
            <Bar
              v-if="pageData.detail.results"
              :list="pageData.detail.results"
              labelShow="top"
            />
            <Bar
              v-if="pageData.detail.topicResults"
              :list="pageData.detail.topicResults"
              :isMulti="true"
              :multiOptions="pageData.detail.options"
              listKey="topic"
              labelShow="top"
              :color="['rgb(80, 135, 236)', 'rgb(104, 187, 196)', 'rgb(238, 117, 47)']"
            />
          </div>
        </div>
      </div>
    </app-page-main>

    <template #footer>
      <div class="app-toolbar" v-if="$route.query.id">
        <el-button @click="$router.go(-1)">返回</el-button>
      </div>

      <el-button class="app-ml-15" :loading="data.statLoading" type="success" plain @click="handleResults"
        >下载结果</el-button
      >
    </template>
  </app-page>
</template>

<script setup>
import Bar from '@/components/echarts/Bar.vue'
import { usePageEdit, http } from 'jax-node'
import { ElMessage } from 'element-plus'
import html2canvas from 'html2canvas'

const route = useRoute()
const { pageData, pageActions } = usePageEdit({
  api: 'meet/vote/count',
})

const data = reactive({
  maxRow: 0,
  maxCol: 0,
  list: [],

  voteDetail: {},
  statLoading: false,
})

// 计算格子与数据结合
const gridCells = computed(() => {
  const cells = []
  if (data.maxRow && data.maxCol) {
    for (let i = 1; i <= data.maxRow; i++) {
      for (let j = 1; j <= data.maxCol; j++) {
        const matched = data.list.find(item => item.seatRow === i && item.seatCol === j)
        cells.push(matched ? matched : { seatRow: i, seatCol: j })
      }
    }
  }
  return cells
})

pageActions.getData = async () => {
  await http
    .get(pageData.api, {
      params: {
        voteId: route.query.id,
      },
    })
    .then(res => {
      pageData.detail = res
      data.list = res.users
    })

  await http.get(`/meet/room/${route.query.roomId}`).then(res => {
    data.maxRow = res.maxRow
    data.maxCol = res.maxCol
  })

  // 获取投票详情
  http.get(`/meet/vote/${route.query.id}`).then(res => {
    data.voteDetail = res
  })
}

const statRef = ref(null)
const handleResults = () => {
  if (!statRef.value) return
  if (pageData.detail.results?.length <= 0 || pageData.detail.topicResults?.length <= 0) {
    ElMessage.error('无数据导出')
    return
  }
  data.statLoading = true
  html2canvas(statRef.value, {
    useCORS: true,
    allowTaint: true,
  })
    .then(canvas => {
      const dataUrl = canvas.toDataURL('image/png')
      const a = document.createElement('a')
      a.href = dataUrl
      a.download = `${data.voteDetail.title}-投票统计结果.png`
      a.click()
      ElMessage.success('操作成功')
    })
    .finally(() => {
      data.statLoading = false
    })
}
</script>

<style lang="scss" scoped>
.count-main {
  height: 100%;
  width: 1500px;
  &__meet {
    display: grid;
    grid-template-rows: 1fr auto;
    height: 600px;
    width: 100%;
    &-body {
      height: 100%;
      min-height: 0;
      background-color: #f8f8f8;
      overflow: hidden;
    }
    &-wrapper {
      --location-width: 55px;
      --location-height: 25px;
      position: relative;
      overflow: auto;
      min-height: 0;
      height: 100%;
      .area-wrapper--top {
        position: -webkit-sticky;
        position: sticky;
        top: 0;
        left: 50px;
        padding: 10px;
        display: grid;
        grid-template-columns: repeat(var(--location-column), var(--location-width));
        grid-gap: 10px;
        gap: 10px;
        justify-content: center;
        text-align: center;
        background-color: rgba(#000, 0.3);
        color: #fff;
      }
      .area-wrapper--left {
        position: absolute;
        top: 50px;
        left: 0;
        display: grid;
        grid-template-rows: repeat(var(--location-row), var(--location-height));
        grid-gap: 10px;
        gap: 10px;
        line-height: var(--location-height);
        background-color: rgba(#000, 0.3);
        color: #fff;
        text-align: center;
        &-locale {
          width: 40px;
        }
      }
      &--area {
        display: grid;
        grid-template-columns: repeat(var(--location-column), var(--location-width));
        grid-template-rows: repeat(var(--location-row), var(--location-height));
        grid-gap: 10px;
        gap: 10px;
        padding: 10px 20px 20px 40px;
        .location-wrapper-square {
          line-height: var(--location-height);
          background-color: var(--el-color-warning);
          border-radius: 5px;
          text-align: center;
          user-select: none;
          font-size: 12px;
          color: #fff;
          &.voted {
            background-color: var(--el-color-danger);
          }
          &.unvoted {
            background-color: #fff;
            border: 1px solid #35a3ff;
            color: #000;
          }
        }
      }
    }
  }
  &__stat {
    display: grid;
    grid-template-rows: auto auto 1fr;
    height: 500px;
    &-header {
      margin-top: 15px;
      text-align: center;
      &--title {
        font-size: 16px;
        font-weight: bold;
      }
      &--time {
        margin-top: 10px;
      }
    }
    &-body {
      width: 100%;
      height: 100%;
    }
  }
  .vote-result {
    gap: 15px;
    justify-content: center;
    padding: 8px 0;
    background-color: var(--el-color-primary-light-5);
    text-align: center;
    color: #fff;
    font-size: 16px;
    font-weight: bold;
  }
}
</style>
